package de.fhwf.mixedreality.client;

import java.io.IOException;
import java.net.BindException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;

public class UDPConnection {
 private static final int MAX_MESSAGE_LEN = 8 * 1024;
 
 private DatagramSocket mSocket;
 private DatagramPacket mSendPacket = new DatagramPacket(new byte[MAX_MESSAGE_LEN], MAX_MESSAGE_LEN);
 private InetAddress mServerAddress;
 private int mServerPort;
 
 public UDPConnection(String serverAddress, int serverPort) {
  try {
   mServerAddress = InetAddress.getByName(serverAddress);
  } catch (UnknownHostException e) {
   System.err.println("[UDPConnection] UDPConnection: Error resolving address: " + e.getMessage());   
  }
  mServerPort = serverPort;
  int clientPort = 12300 - 1;
  boolean success = false;
  while (clientPort < 12350 && !success) {
   clientPort++;
   try {
    success = true;
    mSocket = new DatagramSocket(clientPort);
   } catch (BindException e) {
    success = false;
   } catch (SocketException e) {
    success = false;
    System.err.println("[UDPConnection] UDPConnection: Error creating socket: " + e.getMessage());
   }
  }
  mSendPacket.setAddress(mServerAddress);
  mSendPacket.setPort(mServerPort);
  System.out.println("[UDPConnection] UDPConnection: Connection will be established from port " + clientPort + ".");
 }
 
 public void send(String data) {
//	System.out.println("[UDPConnection] send: Sending " + data);
  mSendPacket.setData(data.getBytes());
  try {
   mSocket.send(mSendPacket);
  } catch (IOException e) {
   System.err.println("[UDPConnection] send: Error sending data: " + e.getMessage());   
  }
 }
 
 public String receive() {
  DatagramPacket recvPacket = new DatagramPacket(new byte[MAX_MESSAGE_LEN], MAX_MESSAGE_LEN);
  boolean timeout = false;
  try {
   mSocket.setSoTimeout(1000);
   try {
    mSocket.receive(recvPacket);
   } catch (SocketTimeoutException e) {
    timeout = true;
   }
  } catch (SocketException e) {
   System.err.println("[UDPConnection] receive: Error receiving socket: " + e.getMessage());
  } catch (IOException e) {
   System.err.println("[UDPConnection] receive: Error receiving packet: " + e.getMessage());
  } 
  if (!timeout) {
   //System.out.println("[UDPConnection] Received Information: " + new String(recvPacket.getData(),0,recvPacket.getLength()));
   return new String(recvPacket.getData(), 0, recvPacket.getLength());
  } else {
   return "";
  }
 }
 
 public void close() {
  mSocket.close();
 }
}
